'use strict';
const path = require('path');
const fs = require('fs');
const Controller = require('egg').Controller;

class FileController extends Controller {
	async search() {
		const { ctx, app } = this;
		const user_id = ctx.authUser.id;
		ctx.validate({
			keyword: { required: true, type: 'string', desc: '关键词' }
		});
		let { keyword } = ctx.query;
		const Op = app.Sequelize.Op;
		let rows = await app.model.File.findAll({
			where: {
				name: {
					// 包含
					[Op.like]: `%${keyword}%`
				},
				isdir: 0,
				user_id
			}
		});
		ctx.Success(rows);
	}
	async delete() {
		const { ctx, app } = this;
		const user_id = ctx.authUser.id;

		ctx.validate({ ids: { type: 'string', required: true, desc: '目录ID' } });

		let { ids } = ctx.request.body;
		ids = ids.split(',');

		// 计算删除文件内存
		let files = await app.model.File.findAll({
			where: {
				id: ids,
				user_id
			}
		});

		let size = 0;
		files.forEach(item => {
			size = size + item.size;
		});

		// 删除
		let res = await app.model.File.destroy({
			where: {
				id: ids,
				user_id
			}
		});

		// 消除内存
		if (res) {
			size = ctx.authUser.used_size - size;
			ctx.authUser.used_size = size > 0 ? size : 0;
			ctx.authUser.save();
		}
		ctx.Success(res);
	}
	async editName() {
		const { ctx, service } = this;
		ctx.validate({
			id: { type: 'int', required: true, defValue: 0, desc: '目录ID' },
			name: { type: 'string', required: true, desc: '文件夹名称' }
		});
		const { id, name } = ctx.request.body;
		// 判断文件是否存在

		const f = await service.file.isExist(id);
		f.name = name;
		const res = await f.save();
		ctx.Success(res);
	}
	async createDir() {
		const { ctx, app, service } = this;
		const user_id = ctx.authUser.id;

		ctx.validate({
			file_id: { type: 'int', required: true, defValue: 0, desc: '目录ID' },
			name: { type: 'string', required: true, desc: '文件夹名称' }
		});

		const { file_id, name } = ctx.request.body;
		// 验证目录是否存在
		if (file_id) {
			await service.file.isDirExist(file_id);
		}

		const res = await app.model.File.create({
			name,
			file_id,
			user_id,
			isdir: 1,
			size: 0
		});
		ctx.Success(res);
	}
	async list() {
		const { ctx, app } = this;
		const user_id = ctx.authUser.id;
		ctx.validate({
			file_id: { type: 'int', required: true, desc: '目录ID', defValue: 0 },
			orderby: {
				type: 'string',
				defValue: 'name',
				required: false,
				range: { in: ['name', 'created_time'] },
				desc: '排序'
			},
			type: {
				required: false,
				type: 'string',
				desc: '类型'
			},
			isdir: {
				required: false,
				type: 'int',
				rang: {
					in: [0, 1, 2]
				},
				desc: '只查询目录',
				defValue: 2
			}
		});
		const { file_id, orderby, type, isdir } = ctx.query;
		let where = { user_id, file_id };
		if (type && type !== 'all') {
			const Op = app.Sequelize.Op;
			where.ext = {
				[Op.like]: type + '%'
			};
		}
		if (isdir && isdir !== 2) {
			where.isdir = isdir;
		}
		// 降序
		let rows = await app.model.File.findAll({
			where,
			order: [
				['isdir', 'desc'],
				[orderby, 'desc']
			]
		});
		ctx.Success(rows);
	}
	async upload() {
		const { ctx, app, service } = this;
		const currentUser = ctx.authUser;
		// 验证file_id:目录ID 默认0

		ctx.validate({
			file_id: { type: 'int', defValue: 0, required: true, desc: '目录ID' }
		});
		// 判断是否有文件上传

		const file_id = ctx.query.file_id;
		const file = ctx.request.files[0];
		if (!file) {
			ctx.throw(404, '请选择上传文件!');
		}
		if (file_id > 0) {
			// 判断目录是否存在
			await service.file.isDirExist(file_id);
		}
		// 目录存在的话,拼接目录
		const fileName = 'egg-disk/' + ctx.genID() + path.extname(file.filename);
		// 读取文件大小，转为字节
		const F = await new Promise((resolve, reject) => {
			fs.stat(file.filepath, (err, stats) => {
				resolve((stats.size / 1024).toFixed(1));
			});
		});
		// 验证用户内存是否已满
		if (currentUser.total_size - currentUser.used_size < F) {
			return ctx.Fail('剩余空间不足,请扩充！');
		}
		// 推送文件到oss
		let result;
		try {
			result = await app.fullQiniu.uploadFile(fileName, file.filepath);
		} catch (error) {
			ctx.throw(500, '服务推送失败');
		}
		if (result) {
			// 写入数据表
			let pushData = {
				name: file.filename,
				ext: file.mimeType,
				md: result.key,
				file_id,
				user_id: currentUser.id,
				size: parseInt(F),
				isdir: 0,
				url: result.url
			};

			if (file_id > 0) {
				pushData.file_id = file_id;
			}
			const res = await app.model.File.create(pushData);
			// 更新使用内存

			currentUser.used_size = currentUser.used_size + parseInt(F);
			currentUser.save();
			return ctx.Success(res);
		}
		ctx.Fail('文件上传失败!');
	}
	async dirList() {
		const { ctx, app, service } = this;
		const userId = ctx.authUser.id;

		const rows = await app.model.File.findAll({
			where: {
				user_id: userId,
				isdir: 1
			}
		});
		const result = await service.file.formDir(rows);
		ctx.Success(result);
	}
}

module.exports = FileController;
